<template>
  <teleport to="body">
    <div 
      v-if="visible"
      :class="[
        'bx-back-top',
        'bx-glass',
        {
          'bx-back-top--visible': visible
        }
      ]"
      :style="backTopStyle"
      @click="handleClick"
    >
      <slot>
        <BxIcon name="arrow-up" />
      </slot>
    </div>
  </teleport>
</template>

<script>
import { ref, computed, onMounted, onUnmounted } from 'vue'
import BxIcon from '../basic/BxIcon.vue'

export default {
  name: 'BxBackTop',
  components: {
    BxIcon
  },
  props: {
    visibilityHeight: {
      type: Number,
      default: 400
    },
    right: {
      type: Number,
      default: 40
    },
    bottom: {
      type: Number,
      default: 40
    },
    duration: {
      type: Number,
      default: 450
    },
    target: {
      type: [String, Object],
      default: null
    }
  },
  emits: ['click'],
  setup(props, { emit }) {
    const visible = ref(false)
    let targetElement = null

    const backTopStyle = computed(() => {
      return {
        right: `${props.right}px`,
        bottom: `${props.bottom}px`
      }
    })

    const getScrollTop = () => {
      if (targetElement) {
        return targetElement.scrollTop
      }
      return document.documentElement.scrollTop || document.body.scrollTop
    }

    const scrollToTop = () => {
      const scrollElement = targetElement || window
      const startTime = Date.now()
      const startScrollTop = getScrollTop()

      const scroll = () => {
        const elapsed = Date.now() - startTime
        const progress = Math.min(elapsed / props.duration, 1)
        
        // 使用缓动函数
        const easeInOutQuad = progress < 0.5 
          ? 2 * progress * progress 
          : 1 - Math.pow(-2 * progress + 2, 2) / 2

        const currentScrollTop = startScrollTop * (1 - easeInOutQuad)

        if (targetElement) {
          targetElement.scrollTop = currentScrollTop
        } else {
          window.scrollTo(0, currentScrollTop)
        }

        if (progress < 1) {
          requestAnimationFrame(scroll)
        }
      }

      requestAnimationFrame(scroll)
    }

    const handleScroll = () => {
      const scrollTop = getScrollTop()
      visible.value = scrollTop >= props.visibilityHeight
    }

    const handleClick = (event) => {
      scrollToTop()
      emit('click', event)
    }

    onMounted(() => {
      // 确定目标元素
      if (props.target) {
        if (typeof props.target === 'string') {
          targetElement = document.querySelector(props.target)
        } else {
          targetElement = props.target
        }
      }

      // 添加滚动监听
      if (targetElement) {
        targetElement.addEventListener('scroll', handleScroll, { passive: true })
      } else {
        window.addEventListener('scroll', handleScroll, { passive: true })
      }

      // 初始检查
      handleScroll()
    })

    onUnmounted(() => {
      if (targetElement) {
        targetElement.removeEventListener('scroll', handleScroll)
      } else {
        window.removeEventListener('scroll', handleScroll)
      }
    })

    return {
      visible,
      backTopStyle,
      handleClick
    }
  }
}
</script>

<style scoped>
.bx-back-top {
  position: fixed;
  width: 48px;
  height: 48px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--bx-glass-bg);
  backdrop-filter: var(--bx-glass-blur-strong);
  border: 1px solid var(--bx-glass-border);
  border-radius: 50%;
  cursor: pointer;
  transition: all var(--bx-transition-medium);
  z-index: 1000;
  color: var(--bx-text-primary);
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.15);
  opacity: 0;
  transform: scale(0.8);
  pointer-events: none;
}

.bx-back-top--visible {
  opacity: 1;
  transform: scale(1);
  pointer-events: auto;
}

.bx-back-top:hover {
  background: var(--bx-glass-bg-hover);
  border-color: var(--bx-glass-border-hover);
  transform: scale(1.1);
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.2);
}

.bx-back-top:active {
  transform: scale(1.05);
}

.bx-back-top::before {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: linear-gradient(
    135deg,
    rgba(255, 255, 255, 0.2) 0%,
    rgba(255, 255, 255, 0.1) 100%
  );
  border-radius: inherit;
  opacity: 0;
  transition: opacity var(--bx-transition-medium);
  pointer-events: none;
}

.bx-back-top:hover::before {
  opacity: 1;
}

.bx-back-top :deep(svg) {
  width: 20px;
  height: 20px;
}

/* 脉冲动画 */
@keyframes bx-back-top-pulse {
  0%, 100% {
    box-shadow: 0 4px 16px rgba(0, 0, 0, 0.15);
  }
  50% {
    box-shadow: 0 4px 16px rgba(0, 0, 0, 0.15), 0 0 0 8px rgba(0, 122, 255, 0.1);
  }
}

.bx-back-top--visible {
  animation: bx-back-top-pulse 3s ease-in-out infinite;
}

/* 响应式设计 */
@media (max-width: 768px) {
  .bx-back-top {
    width: 44px;
    height: 44px;
  }
  
  .bx-back-top :deep(svg) {
    width: 18px;
    height: 18px;
  }
}
</style>

